package com.tbvtc.agriculturalcreditchainserver2025.utils.recognize;

import com.tbvtc.agriculturalcreditchainserver2025.entity.recognize.OcrResponse;
import com.tbvtc.agriculturalcreditchainserver2025.entity.recognize.OcrResult;
import com.tbvtc.agriculturalcreditchainserver2025.entity.recognize.WordResult;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.stream.Collectors;

@Component
public class OcrDataProcessor {

    /**
     * 处理OCR结果，将同一行的标签和值关联
     */
    public Map<Integer, String> process(OcrResponse ocrResult) {
        Map<Integer, String> resultMap = new LinkedHashMap<>(); // 保留顺序
        List<WordResult> wordItems = ocrResult.getWords_result();

        // 1. 按top坐标分组（允许±5px误差，视为同一行）
        Map<Integer, List<WordResult>> rowGroups = new HashMap<>();
        for (WordResult item : wordItems) {
            int top = item.getLocation().getTop();
            // 查找已有分组中top接近的组（误差±）
            //查找完成后将相似的都改为第一个top值
            Integer targetTop = rowGroups.keySet().stream()
                    .filter(t -> Math.abs(t - top) <= 20)
                    .findFirst()
                    .orElse(top);
            // 无则新建组
            rowGroups.computeIfAbsent(targetTop, k -> new ArrayList<>()).add(item);
        }

        // 2. 遍历每组（行），按left排序后组装键值对
        for (List<WordResult> row : rowGroups.values()) {
            // 按left坐标升序排序（左侧为标签，右侧为值）
            List<WordResult> sortedRow = row.stream()
                    .sorted(Comparator.comparingInt(i -> i.getLocation().getLeft()))
                    .collect(Collectors.toList());

            // 3. 组装键值对（若一行有多个字段，按顺序关联，如"标签1:值1, 标签2:值2"）
            StringBuilder rowContent = new StringBuilder();
            for (int i = 0; i < sortedRow.size(); i++) {
                rowContent.append(sortedRow.get(i).getWords());
                if (i < sortedRow.size() - 1) {
                    rowContent.append(": "); // 用冒号分隔标签和值
                }
            }

            // 若需要按原文档顺序保存，可按top排序后存入LinkedHashMap
            resultMap.put(sortedRow.get(0).getLocation().getTop(), rowContent.toString());
        }
        HashMap<Integer, String> collect = resultMap.entrySet().stream().sorted(new Comparator<Map.Entry<Integer, String>>() {
            @Override
            public int compare(Map.Entry<Integer, String> o1, Map.Entry<Integer, String> o2) {
                return o1.getKey() - o2.getKey();
            }
        }).collect(Collectors.toMap(
                Map.Entry::getKey,
                Map.Entry::getValue,
                (oldValue, newValue) -> oldValue,
                HashMap::new
        ));
        return resultMap;
    }
}